package com.kerrykidz.sales.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.kerrykidz.common.ORDER_CONSTANTS;
import com.kerrykidz.common.PrimaryKeyGenerator;
import com.kerrykidz.common.PrimaryKeyGenerator.BusinessType;
import com.kerrykidz.membership.dao.model.CusMemEntity;
import com.kerrykidz.membership.service.IMemberService;
import com.kerrykidz.sales.dao.mapper.PosOrderEntityMapper;
import com.kerrykidz.sales.dao.mapper.PosOrderPrdEntityMapper;
import com.kerrykidz.sales.dao.model.OrderRecord;
import com.kerrykidz.sales.dao.model.PosOrderEntity;
import com.kerrykidz.sales.dao.model.PosOrderPaymentEntity;
import com.kerrykidz.sales.dao.model.PosOrderPrdEntity;
import com.kerrykidz.sales.service.IOrderService;
import com.kerrykidz.sales.service.IPaymentService;
import com.kerrykidz.system.util.UserUtil;
import com.kerrykidz.system.util.printReceipt.PrintHelper;
import com.kerrykidz.system.util.printReceipt.PrinterMessage;
import com.kerrykidz.system.util.printReceipt.PrinterOrderDetail;

@Service
public class OrderServiceImpl implements IOrderService {

	@Autowired
	private PosOrderEntityMapper posOrderEntityMapper;

	@Autowired
	private PosOrderPrdEntityMapper posOrderPrdEntityMapper;

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private IPaymentService paymentService;

	@Autowired
	private IMemberService memberService;

	@Override
	public PosOrderEntity findOrderByPk(String pkId) {
		return this.posOrderEntityMapper.findOrderByPk(pkId);
	}

	@Override
	public String createNotPayOfOrder(PosOrderEntity order, List<PosOrderPrdEntity> products, String storeName)
			throws Exception {
		if (StringUtils.isBlank(order.getOrderStatus()))
			throw new Exception("订单状态不能为空!");
		else if (StringUtils.isBlank(order.getOrderType()))
			throw new Exception("订单类型不正确");
		else if (StringUtils.isBlank(storeName))
			throw new Exception("门店缩写不能为空!");
		else if (products == null || products.size() == 0)
			throw new Exception("商品信息不能为空");
		else if (StringUtils.isBlank(order.getOrderType()))
			throw new Exception("订单类型不能为空");

		String orderPk = PrimaryKeyGenerator.getPrimaryKey(BusinessType.XS, storeName);

		/*
		 * 设置订单参数
		 */
		order.setPkOrderId(orderPk);
		order.setOperateTime(new Date());
		order.setModiTime(new Date());
		order.setRetFlag(ORDER_CONSTANTS.RET_FLAG_NO);

		/*
		 * 设置商品
		 */
		for (PosOrderPrdEntity prd : products) {
			prd.setPkOrdprdId(PrimaryKeyGenerator.getRandomPrimaryKey());
			prd.setPkOrderId(orderPk);
			if (StringUtils.isBlank(prd.getType()))
				throw new Exception("商品类型不能为空");
			if (prd.getPrice() == null || prd.getDisPrice() == null)
				throw new Exception("商品Price和DisPrice都不能为空");
		}

		this.posOrderEntityMapper.insert(order);
		this.posOrderPrdEntityMapper.batchInsert(products);
		return orderPk;
	}

	@Override
	public String createTicket(PosOrderEntity order, List<PosOrderPrdEntity> tickets, PosOrderPrdEntity recharge,
			String storeName)
			throws Exception {
		if (StringUtils.isBlank(order.getOrderStatus()))
			throw new Exception("订单状态不能为空!");
		else if (!"1".equals(order.getOrderType()) && "4".equals(order.getOrderType()))
			throw new Exception("订单类型不正确");
		else if (StringUtils.isBlank(storeName))
			throw new Exception("门店缩写不能为空");
		else if (tickets == null)
			throw new Exception("至少得有一张票");

		String orderPk = PrimaryKeyGenerator.getPrimaryKey(BusinessType.XS, storeName);

		/*
		 * 设置订单参数
		 */
		order.setPkOrderId(orderPk);
		order.setOrderType(ORDER_CONSTANTS.ORDER_TYPE_TICKET);
		order.setRetFlag(ORDER_CONSTANTS.RET_FLAG_NO);
		order.setOperateTime(new Date());
		order.setModiTime(new Date());

		this.posOrderEntityMapper.insert(order);

		List<PosOrderPrdEntity> details = new ArrayList<PosOrderPrdEntity>();

		/*
		 * 是否有充值操作
		 */
		if (recharge != null) {
			if (recharge.getCount() == null) {
				throw new Exception("充值金额不能为空");
			}
			recharge.setPkOrderId(orderPk);
			recharge.setType(ORDER_CONSTANTS.ORDER_PRD_TYPE_CHARGE);
			recharge.setPkOrdprdId(PrimaryKeyGenerator.getRandomPrimaryKey());
			details.add(recharge);
		}

		/*
		 * 购买的票
		 */
		for (PosOrderPrdEntity ticket : tickets) {
			ticket.setPkOrdprdId(PrimaryKeyGenerator.getRandomPrimaryKey());
			ticket.setPkOrderId(orderPk);
			if (StringUtils.isBlank(ticket.getType()))
				throw new Exception("商品类型不能为空");
			if (StringUtils.isBlank(ticket.getFkMemId()))
				throw new Exception("所购票必须要指定会员或非会员");
			if (StringUtils.isBlank(ticket.getFkDisId()))
				ticket.setFkDisId(null);
			if (StringUtils.isBlank(ticket.getFkDisusrId()))
				ticket.setFkDisusrId(null);
			details.add(ticket);
		}

		for (PosOrderPrdEntity prd : details)
			if (prd.getPrice() == null || prd.getDisPrice() == null)
				throw new Exception("商品Price和DisPrice都不能为空");

		this.posOrderPrdEntityMapper.batchInsert(details);

		return orderPk;
	}

	@Override
	public String createHavePayOfOrder(PosOrderEntity order, List<PosOrderPrdEntity> products,
			PosOrderPaymentEntity payment,
			String storeName) throws Exception {
		if (StringUtils.isBlank(order.getOrderStatus()))
			throw new Exception("订单状态不能为空!");
		else if (StringUtils.isBlank(storeName))
			throw new Exception("门店缩写不能为空!");
		else if (products == null || products.size() == 0)
			throw new Exception("商品信息不能为空");

		String orderPk = PrimaryKeyGenerator.getPrimaryKey(BusinessType.XS, storeName);

		/*
		 * 设置订单参数
		 */
		order.setPkOrderId(orderPk);
		order.setOperateTime(new Date());
		order.setModiTime(new Date());
		order.setRetFlag(ORDER_CONSTANTS.RET_FLAG_NO);

		/*
		 * 设置商品
		 */
		for (PosOrderPrdEntity prd : products) {
			prd.setPkOrdprdId(PrimaryKeyGenerator.getRandomPrimaryKey());
			prd.setPkOrderId(orderPk);
			if (StringUtils.isBlank(prd.getType()))
				throw new Exception("商品类型不能为空");
			if (prd.getPrice() == null || prd.getDisPrice() == null)
				throw new Exception("商品Price和DisPrice都不能为空");
		}

		if (payment != null) {
			order.setOrderStatus(ORDER_CONSTANTS.ORDER_STATUS_PREPAY);
		}

		this.posOrderEntityMapper.insert(order);
		this.posOrderPrdEntityMapper.batchInsert(products);

		if (payment != null)
			this.paymentService.createRepay(payment);

		return orderPk;
	}

	@Override
	public PosOrderEntity paginate(PosOrderEntity order) {
		order.setIspaging(true);
		List<PosOrderEntity> list = this.posOrderEntityMapper.paginate(order);

		if (list.size() > 0) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
			for (PosOrderEntity p : list) {
				p.setTime(sdf);
				p.setTime2(sdf);
			}
			order.setResults(list);
		}
		return order;
	}

	@Override
	public List<PosOrderPrdEntity> findOrderPrdByOrderId(String orderId) {
		return this.posOrderPrdEntityMapper.findByOrderId(orderId);
	}

	@Override
	public void finishPayment(String orderId) throws Exception {
		synchronized (orderId) {
			this.updateOrderModiTime(orderId);
			this.posOrderEntityMapper.finishPayment(orderId);
		}
	}

	@Override
	public void updateOrder(PosOrderEntity order, List<PosOrderPrdEntity> products) throws Exception {
		if (StringUtils.isBlank(order.getPkOrderId()))
			throw new Exception("订单号不能为空");
		synchronized (order.getPkOrderId()) {
			this.posOrderEntityMapper.updateByPrimaryKeySelective(order);
			this.posOrderPrdEntityMapper.removeByOrderId(order.getPkOrderId());
			this.createOrderPrd(products);
		}
	}

	@Override
	public PosOrderEntity findByCondition(PosOrderEntity order) {
		return this.posOrderEntityMapper.findByCondition(order);
	}

	@Override
	public void updateOrderProduct(PosOrderPrdEntity prd) throws Exception {
		if (StringUtils.isBlank(prd.getPkOrderId())) {
			throw new Exception("订单编号不能为空!");
		} else if (StringUtils.isBlank(prd.getFkPrdId())) {
			throw new Exception("商品编号不能为空!");
		} else if (prd.getCount() == null || prd.getCount() < 0) {
			throw new Exception("商品数量不正确!");
		}
		synchronized (prd.getPkOrderId()) {
			this.updateOrderModiTime(prd.getPkOrderId());
			this.posOrderPrdEntityMapper.update(prd);
		}
	}

	@Override
	public PosOrderPrdEntity findOrderPrdByCondition(PosOrderPrdEntity prd) {
		return this.posOrderPrdEntityMapper.findbyCondition(prd);
	}

	@Override
	public void createOrderPrd(List<PosOrderPrdEntity> prds) throws Exception {
		if (prds != null) {
			String orderId = null;
			/*
			 * 设置商品
			 */
			for (PosOrderPrdEntity prd : prds) {
				orderId = prd.getPkOrderId();
				if (StringUtils.isBlank(prd.getPkOrderId()))
					throw new Exception("商品明细订单号不能为空");
				if (prd.getPrice() == null || prd.getDisPrice() == null)
					throw new Exception("商品Price和DisPrice都不能为空");
				prd.setType(ORDER_CONSTANTS.ORDER_PRD_TYPE_PRODUCT);
				prd.setPkOrdprdId(PrimaryKeyGenerator.getRandomPrimaryKey());
			}
			if (orderId != null)
				this.updateOrderModiTime(orderId);
			this.posOrderPrdEntityMapper.batchInsert(prds);
		}
	}

	@Override
	public void createShopcart(PosOrderEntity order) throws Exception {
		if (StringUtils.isBlank(order.getPkOrderId()))
			throw new Exception("订单编号不能为空");
		else if (!ORDER_CONSTANTS.ORDER_STATUS_SHOPCART.equals(order.getOrderStatus()))
			throw new Exception("订单状态只能为购物车");
		else if (!ORDER_CONSTANTS.ORDER_TYPE_PRODUCT.equals(order.getOrderType()))
			throw new Exception("订单类型只能为普通商品");
		order.setModiTime(new Date());
		this.posOrderEntityMapper.insert(order);
	}

	@Override
	public PosOrderEntity createAndfindCurrentShopCart(String userId, String abbrCode, String branId) {
		PosOrderEntity order = new PosOrderEntity();
		order.setPkOrderId(PrimaryKeyGenerator.getPrimaryKey(BusinessType.XS, abbrCode));
		order.setOrderType(ORDER_CONSTANTS.ORDER_TYPE_PRODUCT);
		order.setOrderStatus(ORDER_CONSTANTS.ORDER_STATUS_SHOPCART);
		order.setRetFlag(ORDER_CONSTANTS.RET_FLAG_NO);
		order.setFkOperator(userId);
		order.setOperateTime(new Date());
		order.setFkBranId(branId);
		order.setModiTime(new Date());
		try {
			this.createShopcart(order);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return order;
	}

	public void updateOrder(PosOrderEntity orderOld) {
		synchronized (orderOld.getPkOrderId()) {
			orderOld.setModiTime(new Date());
			this.posOrderEntityMapper.updateByPrimaryKeySelective(orderOld);
		}

	}

	public void removeOrderPrdByOrderId(String orderId) {
		synchronized (orderId) {
			updateOrderModiTime(orderId);
			this.posOrderPrdEntityMapper.removeByOrderId(orderId);
		}
	}

	private void updateOrderModiTime(String orderId) {
		PosOrderEntity order = new PosOrderEntity();
		order.setPkOrderId(orderId);
		order.setModiTime(new Date());
		this.posOrderEntityMapper.updateByPrimaryKeySelective(order);
	}

	@Override
	public synchronized boolean checkGiftNo(String giftNo) {
		PosOrderEntity order = new PosOrderEntity();
		order.setGiftNo("," + giftNo + ",");
		order.setOrderStatus(ORDER_CONSTANTS.ORDER_STATUS_HAS_BEEN_PAY);
		List<PosOrderEntity> list = this.posOrderEntityMapper.findCollectionByCondition(order);
		return list == null || list.size() == 0;
	}

	@Override
	public void removeOrderPrdByOrderIdAndProductId(String orderId, String prdId) {
		this.updateOrderModiTime(orderId);
		this.posOrderPrdEntityMapper.removeByOrderIdAndPrdId(orderId, prdId);
	}

	@Override
	public List<OrderRecord> findOrderRecord(String orderId) throws Exception {
		List<OrderRecord> list = new ArrayList<OrderRecord>();
		List<PosOrderPaymentEntity> payments = this.paymentService.findByOrderPk(orderId);
		for (PosOrderPaymentEntity p : payments)
			list.add(new OrderRecord(p));

		PosOrderEntity order = new PosOrderEntity();
		order.setFkOriorderId(orderId);

		List<PosOrderEntity> orders = this.findOrderCollectionsByCondition(order);
		for (PosOrderEntity o : orders)
			list.add(new OrderRecord(o));
		Collections.sort(list);
		return list;
	}

	@Override
	public String recharge(String memId, double amount, String operator, String storeName, String branId)
			throws Exception {
		String orderId = PrimaryKeyGenerator.getPrimaryKey(BusinessType.CZ, storeName);
		Date now = new Date();

		if (StringUtils.isBlank(memId)) {
			throw new Exception("memId不能为空");
		} else if (StringUtils.isBlank(operator)) {
			throw new Exception("operator不能为空");
		} else if (StringUtils.isBlank(storeName)) {
			throw new Exception("storeName不能为空");
		} else if (StringUtils.isBlank(branId)) {
			throw new Exception("branId不能为空");
		} else if (amount <= 0) {
			throw new Exception("充值金额必须至少大于0");
		}

		/*
		 * 先创建充值订单信息
		 */

		CusMemEntity cusMem = memberService.findMemberById(memId);
		if (null == cusMem) {
			throw new Exception("memId不能为空");
		}

		PosOrderEntity order = new PosOrderEntity();
		order.setPkOrderId(orderId);
		order.setOrderType(ORDER_CONSTANTS.ORDER_TYPE_RECHARGE);
		order.setOrderStatus(ORDER_CONSTANTS.ORDER_STATUS_NOT_PAY);
		order.setRetFlag(ORDER_CONSTANTS.RET_FLAG_NO);
		order.setAmount(amount);
		order.setOperateTime(now);
		order.setFkOperator(operator);
		order.setCusName(cusMem.getMemName());
		order.setFkBranId(branId);
		order.setModiTime(new Date());

		this.posOrderEntityMapper.insert(order);

		/*
		 * 创建订单商品
		 */

		List<PosOrderPrdEntity> products = new ArrayList<PosOrderPrdEntity>();

		PosOrderPrdEntity prd = new PosOrderPrdEntity();
		prd.setPkOrdprdId(PrimaryKeyGenerator.getRandomPrimaryKey());
		prd.setPkOrderId(orderId);
		prd.setType(ORDER_CONSTANTS.ORDER_PRD_TYPE_CHARGE);
		prd.setCount((int) amount);
		prd.setPrice(new Double("1"));
		prd.setDisPrice(amount);
		prd.setFkMemId(memId);
		products.add(prd);

		this.posOrderPrdEntityMapper.batchInsert(products);

		return orderId;
	}

	@Override
	public String refundGoods(PosOrderEntity order, List<PosOrderPrdEntity> products,
			String storeName) throws Exception {
		if (StringUtils.isBlank(order.getFkBranId()))
			throw new Exception("门店id不能为空");
		else if (StringUtils.isBlank(order.getFkOriorderId()))
			throw new Exception("原订单id不能为空");
		else if (StringUtils.isBlank(order.getFkOperator()))
			throw new Exception("操作人不能为空");

		String orderId = PrimaryKeyGenerator.getPrimaryKey(BusinessType.TH, storeName);
		order.setPkOrderId(orderId);
		order.setOperateTime(new Date());
		order.setRetFlag(ORDER_CONSTANTS.RET_FLAG_YES);
		order.setOrderStatus(ORDER_CONSTANTS.ORDER_STATUS_NOT_PAY);
		for (PosOrderPrdEntity prd : products) {
			prd.setPkOrderId(orderId);
			prd.setPkOrdprdId(PrimaryKeyGenerator.getRandomPrimaryKey());
		}

		order.setModiTime(new Date());
		this.posOrderEntityMapper.insert(order);
		this.posOrderPrdEntityMapper.batchInsert(products);
		return orderId;
	}

	@Override
	public String createRetOrder(PosOrderEntity order, List<PosOrderPrdEntity> prds, String operator, String storeName)
			throws Exception {

		synchronized (order.getFkOriorderId()) {
			String orderId = PrimaryKeyGenerator.getPrimaryKey(BusinessType.TH, storeName);
			if (StringUtils.isBlank(order.getFkOriorderId())) {
				throw new Exception("原订单id不能为空");
			}
			for (PosOrderPrdEntity prd : prds) {
				prd.setPkOrderId(orderId);
				prd.setPkOrdprdId(PrimaryKeyGenerator.getRandomPrimaryKey());
			}
			order.setPkOrderId(orderId);
			order.setFkOperator(operator);
			order.setOperateTime(new Date());
			order.setRetFlag(ORDER_CONSTANTS.RET_FLAG_YES);
			order.setModiTime(new Date());

			this.posOrderEntityMapper.insert(order);
			this.posOrderPrdEntityMapper.batchInsert(prds);
			return orderId;
		}
	}

	@Override
	public List<PosOrderEntity> findOrderCollectionsByCondition(PosOrderEntity order) {
		return this.posOrderEntityMapper.findCollectionByCondition(order);
	}

	public List<PosOrderEntity> findOrderList(PosOrderEntity order) {
		List<PosOrderEntity> list = this.posOrderEntityMapper.paginate(order);

		if (list.size() > 0) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
			for (PosOrderEntity p : list) {
				p.setTime(sdf);
				p.setTime2(sdf);
			}
		}
		return list;
	}

	@Override
	public boolean validaGiftno(String no) {
		List<PosOrderPrdEntity> prds = this.posOrderPrdEntityMapper.validGiftno(no);
		return prds.size() == 0;
	}

	public void printOrderDetail(final String pkOrderId) {
		final List<PrinterMessage> list = posOrderEntityMapper.printOrderDetail(pkOrderId);
		if (list != null && list.size() > 0) {
			new Thread() {
				public void run() {
					String userName = UserUtil.getUserFromSession().getName();
					list.get(0).setCashier(userName);
					PrintHelper.printTicket(new PrinterOrderDetail(list));
				};
			}.start();
		}
	}
	
public List<PrinterMessage> getInfo(String pkOrderId){
	List<PrinterMessage> list = posOrderEntityMapper.printOrderDetail(pkOrderId);
		return list;
}

	@Override
	public boolean isUsedGiftno(String no) {
		List<PosOrderPrdEntity> prds = this.posOrderPrdEntityMapper.isUsedGiftno(no);
		return prds.size() == 0;
	}
}
